/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.yaps.petstore.dao.impl;

import com.yaps.petstore.dao.ItemDAO;
import com.yaps.petstore.entity.catalog.Item;
import com.yaps.petstore.entity.catalog.Product;
import com.yaps.petstore.exception.ValidationException;
import com.yaps.petstore.util.Constants;
import java.util.List;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author belhassine
 */
@Repository("ItemDAO")
public class ItemDAOImpl implements ItemDAO{
    
    @PersistenceContext
    private EntityManager em;
        
        
    private final String cname = this.getClass().getName();
    private Logger logger = Logger.getLogger(Constants.LOGGER_STATELESS);
        
        // ======================================
    // =   Methodes publiques pour article  =
    // ======================================
    @Override
    @Transactional
    public Item createItem(final Item item, final Product product) {
        final String mname = "createItem";
        logger.entering(cname, mname, item);

        // On s'assure de la validité des paramètres
        if (item == null)
            throw new ValidationException("Item object is null");
        if (product == null)
            throw new ValidationException("Item must be attached to a product");

        item.setProduct(product);

        // L'objet est persisté en base de données
        em.persist(item);

        logger.exiting(cname, mname, item);
        return item;
    }

    
    @Override
    @Transactional
    public Item findItem(final Long itemId) {
        final String mname = "findItem";
        logger.entering(cname, mname, itemId);

        // On s'assure de la validité des paramètres
        if (itemId == null)
            throw new ValidationException("Invalid id");

        Item item;

        // On recherche l'objet à partir de son identifiant
        item = em.find(Item.class, itemId);


        logger.exiting(cname, mname, item);
        return item;
    }

    
    @Override
    @Transactional
    public void deleteItem(final Item item) {
        final String mname = "deleteItem";
        logger.entering(cname, mname, item);

        // On s'assure de la validité des paramètres
        if (item == null)
            throw new ValidationException("Item object is null");

        // On supprime l'objet de la base de données
        em.remove(em.merge(item));

        logger.exiting(cname, mname);
    }

    @Override
    @Transactional
    public Item updateItem(final Item item, final Product product) {
        final String mname = "updateItem";
        logger.entering(cname, mname, item);

        // On s'assure de la validité des paramètres
        if (item == null)
            throw new ValidationException("Item object is null");
        if (product == null)
            throw new ValidationException("Item must be attached to a product");

        item.setProduct(product);

        // On modifie l'objet de la base de données
        em.merge(item);

        logger.exiting(cname, mname, item);
        return item;
    }

    
    @Override
    public List<Item> findItems() {
        final String mname = "findCategories";
        logger.entering(cname, mname);

        Query query;
        List<Item> items;

        // On modifie l'objet de la base de données
        query = em.createQuery("SELECT i FROM Item i ORDER BY i.name");
        items = query.getResultList();

        logger.exiting(cname, mname, items.size());
        return items;
    }


    public List<Item> searchItems(final String keyword) {
        final String mname = "searchItems";
        logger.entering(cname, mname, keyword);

        Query query;
        List<Item> items;

        // On modifie l'objet de la base de données
        query = em.createQuery("SELECT i FROM Item i WHERE UPPER(i.name) LIKE :keyword OR UPPER(i.product.name) LIKE :keyword ORDER BY i.product.category.name, i.product.name");
        query.setParameter("keyword", "%" + keyword.toUpperCase() + "%");
        items = query.getResultList();

        logger.exiting(cname, mname, items.size());
        return items;
    }
    // ======================================
    // =           Methodes Privées         =
    // ===============================
    
}
